package com.ruoyi.web.controller.common;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.config.PersonPosition;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.SensorConfig;
import com.ruoyi.common.config.SqlserverConfig;
import com.ruoyi.common.config.oss.OssProperties;
import com.ruoyi.common.config.oss.OssTemplate;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.domain.SysDanger;
import com.ruoyi.system.entity.InspectionPoint;
import com.ruoyi.system.entity.PreventionUnit;
import com.ruoyi.system.mapper.InspectionPlanTaskDetailsMapper;
import com.ruoyi.system.mapper.InspectionPointMapper;
import com.ruoyi.system.mapper.PreventionUnitMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDangerService;
import com.ruoyi.system.service.InspectionPlanTaskDetailsService;
import com.ruoyi.system.service.SysMonitorService;
import com.ruoyi.web.controller.socket.WebSocketController;
import org.apache.tools.ant.taskdefs.condition.Http;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 通用请求处理
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/common")
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private RuoYiConfig ruoYiConfig;

    @Autowired
    private SqlserverConfig sqlserverConfig;

    @Resource
    private SysMonitorService sysMonitorService;

    @Resource
    private ISysDangerService sysDangerService;

    private static final String FILE_DELIMETER = ",";

    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 通用下载请求
     * 
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.checkAllowDownload(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 通用上传请求（多个）
     */
    @PostMapping("/uploads")
    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            List<String> urls = new ArrayList<String>();
            List<String> fileNames = new ArrayList<String>();
            List<String> newFileNames = new ArrayList<String>();
            List<String> originalFilenames = new ArrayList<String>();
            for (MultipartFile file : files)
            {
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = serverConfig.getUrl() + fileName;
                urls.add(url);
                fileNames.add(fileName);
                newFileNames.add(FileUtils.getName(fileName));
                originalFilenames.add(file.getOriginalFilename());
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        try
        {
            if (!FileUtils.checkAllowDownload(resource))
            {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = RuoYiConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    @GetMapping("/geoserver")
    public AjaxResult getGeoserver() {
        System.out.println(JSONUtil.toJsonPrettyStr(ruoYiConfig));
        return AjaxResult.success("success",ruoYiConfig.getWms());
    }

    @GetMapping("/getAlertCount")
    public AjaxResult getAlertCount() {
//        Map<String,Object> map = sysMonitorService.getAlertCount();
        return AjaxResult.success();
    }

    @GetMapping("/getDangerCount")
    public AjaxResult getDangerCount() {
        Map<String,Object> map = sysDangerService.getDangerCount();
        return AjaxResult.success(map);
    }

    @GetMapping("/getHiddenCount")
    public AjaxResult getHiddenCount() {
        Map<String,Object> map = sysDangerService.getHiddenCount();
        return AjaxResult.success(map);
    }

    @Autowired
    private RedisCache redisCache;

    @GetMapping("/setRedis")
    public AjaxResult setRedis(String key,String message) {
        redisCache.setCacheListLeft(key,message);
        return AjaxResult.success();
    }

    /**
     *  获取某个人最后的位置
     * @param nickName  用户昵称
     * @return
     */
    @GetMapping("/getUserAddr")
    public AjaxResult getUserAddr(String nickName) {
        List<Object> cacheList = redisCache.getCacheListNew(nickName);
        return AjaxResult.success(cacheList);
    }

    /**
     *  获取所有人最后的位置
     * @return
     */
    @GetMapping("/getUserAddrAll")
    public AjaxResult getUserAddrAll() {
        List<SysUser> sysUsers = sysUserMapper.selectUserList(new SysUser());
        for (SysUser sysUser : sysUsers) {
            String nickName = sysUser.getNickName();
            List<Object> cacheList = redisCache.getCacheListNew(nickName);
            sysUser.setUserAddr(cacheList);
        }
        return AjaxResult.success(sysUsers);
    }

    /**
     *
     *   SELECT
     * top 10
     * 	t1.JanEmpCardNo,
     * 	t1.ID,
     * 	t2.EmpName,
     * 	t4.DepName,
     * 	t5.JGName,
     * 	t3.JDName,
     * 	t1.WipeDate,
     * 	t1.Legality,
     * 	t1.DoorState
     * FROM
     * 	JanETMonitor t1
     * 	LEFT JOIN Employee t2 ON t1.JanEmpCardNo = t2.CardNo
     * 	LEFT JOIN JanitorData t3 ON t1.JanJDId = t3.JDID
     * 	LEFT JOIN Department t4 ON t2.DepID = t4.DepID
     * 	LEFT JOIN JanitorGrouping t5 ON t3.JGID = t5.JGId
     * ORDER BY t1.ID DESC
     *
     * 查询门禁卡语句 需要研究sqlserver分页
     *
     *
     * @return
     */
    @GetMapping("/sqlserver")
    public AjaxResult sqlserver(Integer pageNum,Integer pageSize,String start,String end) {
        Integer size = pageNum * pageSize;
        // 创造SQL语句
        StringBuffer query = new StringBuffer();
        query.append("SELECT TOP\n");
        query.append("\t");
        query.append(pageSize);
        query.append(" * \n");
        query.append("FROM\n");
        query.append("\t(\n");
        query.append("\tSELECT\n");
        query.append("\t\trow_number ( ) OVER ( ORDER BY t1.ID DESC ) AS rownumber,\n");
        query.append("\t\tt1.JanEmpCardNo,t1.ID,t2.EmpName,t4.DepName,t5.JGName,t3.JDName,t1.WipeDate,t1.Legality,t1.DoorState\n");
        query.append("\tFROM\n");
        query.append("\t\tJanETMonitor t1\n");
        query.append("\t\tLEFT JOIN Employee t2 ON t1.JanEmpCardNo = t2.CardNo\n");
        query.append("\t\tLEFT JOIN JanitorData t3 ON t1.JanJDId = t3.JDID\n");
        query.append("\t\tLEFT JOIN Department t4 ON t2.DepID = t4.DepID\n");
        query.append("\t\tLEFT JOIN JanitorGrouping t5 ON t3.JGID = t5.JGId \n");
        if (StrUtil.isNotEmpty(start) && StrUtil.isNotEmpty(end)) {
            query.append("WHERE t1.WipeDate >= '");
            query.append(start);
            query.append("' AND t1.WipeDate <= '");
            query.append(end);
            query.append("'\n");
        }
        query.append("\t) temp_row \n");
        query.append("WHERE\n");
        query.append("\trownumber > ");
        query.append(size);
        query.append(" \n");
        query.append("ORDER BY\n");
        query.append("\ttemp_row.ID DESC");
        ResultSet rs = null;
        Statement stmt = null;
        Connection conn = null;
        Map<String,Object> result = new HashMap<>();
        try{
            Class.forName(sqlserverConfig.getDriver());// 动态导入数据库的驱动
            conn= DriverManager.getConnection(sqlserverConfig.getUrl(), sqlserverConfig.getUsername(), sqlserverConfig.getPassword());// 获取数据库链接
            stmt=conn.createStatement();// 执行SQL语句
            System.out.println("查询语句： " + query.toString());
            rs=stmt.executeQuery(query.toString());
            Integer total = getTotal();
            result.put("total",total);
            List<Map> list = new ArrayList<>();
            ResultSetMetaData md = rs.getMetaData();//获取键名
            int columnCount = md.getColumnCount();//获取列的数量
            while (rs.next()) {
                Map<String,Object> rowData = new HashMap<>();//声明Map
                for (int i = 1; i <= columnCount; i++) {
                    if (md.getColumnName(i).equals("WipeDate")) {
                        rowData.put(md.getColumnName(i), rs.getObject(i).toString());
                    } else {
                        rowData.put(md.getColumnName(i), rs.getObject(i));//获取键名及值
                    }
                }
                list.add(rowData);
            }
            result.put("data",list);
            System.out.println("查询数据成功");
            rs.close();
            stmt.close();
            conn.close();
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            IoUtil.close(rs);
            IoUtil.close(stmt);
            IoUtil.close(conn);
        }
        return AjaxResult.success(result);
    }

    public Integer getTotal() {
        String totalStr = "\tSELECT\n" +
                "\t\t\tCOUNT(*) total\n" +
                "\tFROM\n" +
                "\t\tJanETMonitor t1\n" +
                "\t\tLEFT JOIN Employee t2 ON t1.JanEmpCardNo = t2.CardNo\n" +
                "\t\tLEFT JOIN JanitorData t3 ON t1.JanJDId = t3.JDID\n" +
                "\t\tLEFT JOIN Department t4 ON t2.DepID = t4.DepID\n" +
                "\t\tLEFT JOIN JanitorGrouping t5 ON t3.JGID = t5.JGId ";
        ResultSet resultSet = null;
        Statement stmt = null;
        Connection conn = null;
        int total = 0;
        try{
            Class.forName(sqlserverConfig.getDriver());// 动态导入数据库的驱动
            conn= DriverManager.getConnection(sqlserverConfig.getUrl(), sqlserverConfig.getUsername(), sqlserverConfig.getPassword());// 获取数据库链接
            stmt=conn.createStatement();// 执行SQL语句
            resultSet = stmt.executeQuery(totalStr);
            resultSet.next();
            total = resultSet.getInt("total");
            resultSet.close();
            stmt.close();
            conn.close();
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            IoUtil.close(resultSet);
            IoUtil.close(stmt);
            IoUtil.close(conn);
        }
        return total;
    }

    @GetMapping("userLogin")
    public AjaxResult userLogin() {

        String login = "";
        try {
            login = PersonPosition.login();
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new ServiceException("当前无法连接到人员定位系统");
        }
        return AjaxResult.success(login);
    }


    @GetMapping("personCount")
    public AjaxResult personCount() {

        Object count = null;
        try {
            count = PersonPosition.count();
        } catch (Exception e) {
            throw new ServiceException("当前无法连接到人员定位系统");
        }
        return AjaxResult.success(count);
    }


    @PostMapping("/send")
    public AjaxResult sendMessage(@RequestBody Map<String,Object> map) throws IOException {
        String message = (String)map.get("message");
        String id = (String)map.get("id");
        WebSocketController.sendInfo(message,id);
        return AjaxResult.success();
    }


    @Resource
    private InspectionPointMapper inspectionPointMapper;
    @Autowired
    private OssTemplate template;
    @Autowired
    private OssProperties ossProperties;
    @Resource
    private PreventionUnitMapper preventionUnitMapper;
    @GetMapping("/load")
    public AjaxResult load(){
        List<InspectionPoint> inspectionPoints = inspectionPointMapper.queryAllByLimit(new InspectionPoint());
        for (InspectionPoint inspectionPoint : inspectionPoints) {
            String objectURL = ossProperties.getAgency() + "/" + ossProperties.getBucketName() + "/" + inspectionPoint.getId() + ".jpg";
            inspectionPoint.setCodeImageFileUrl(HexUtil.encodeHexStr(objectURL));
            inspectionPointMapper.update(inspectionPoint);
        }
        List<PreventionUnit> preventionUnits = preventionUnitMapper.queryAllByLimit(new PreventionUnit());
        for (PreventionUnit preventionUnit : preventionUnits) {
            String objectURL = ossProperties.getAgency() + "/" + ossProperties.getBucketName() + "/" + preventionUnit.getId() + "-prevention.jpg";
            preventionUnit.setZxingUrl(HexUtil.encodeHexStr(objectURL));
            preventionUnitMapper.update(preventionUnit);
        }
        return AjaxResult.success();
    }
}
